import 'package:backend.core/injection_container.dart' as core_di;
import 'package:backend.user_profile/domain/repositories/password_reset_token_repository/repository.dart';
import 'package:backend.user_profile/domain/use_cases/change_email/use_case.dart';
import 'package:backend.user_profile/domain/use_cases/change_password/use_case.dart';
import 'package:backend.user_profile/domain/use_cases/delete_user/use_case.dart';
import 'package:backend.user_profile/domain/use_cases/get_user/use_case.dart';
import 'package:backend.user_profile/domain/use_cases/request_password_reset/use_case.dart';
import 'package:backend.user_profile/domain/use_cases/reset_password/use_case.dart';
import 'package:backend.user_profile/domain/use_cases/run_expired_password_reset_token_deletion/use_case.dart';
import 'package:backend.user_profile/domain/use_cases/verify_email_during_email_change/use_case.dart';
import 'package:backend.user_profile/infrastructure/controllers/email_change_controller/controller.dart';
import 'package:backend.user_profile/infrastructure/controllers/email_verification_during_email_change_controller/controller.dart';
import 'package:backend.user_profile/infrastructure/controllers/password_change_controller/controller.dart';
import 'package:backend.user_profile/infrastructure/controllers/password_reset_controller/controller.dart';
import 'package:backend.user_profile/infrastructure/controllers/password_reset_request_controller/controller.dart';
import 'package:backend.user_profile/infrastructure/controllers/user_deletion_controller/controller.dart';
import 'package:backend.user_profile/infrastructure/controllers/user_getting_controller/controller.dart';
import 'package:backend.user_profile/infrastructure/repositories/password_reset_token_repository/repository.dart';
import 'package:get_it/get_it.dart';

final sl = GetIt.asNewInstance();

Future<void> init() async {
  // controllers

  sl.registerLazySingleton<EmailChangeController>(() {
    return EmailChangeControllerImpl(
      changeEmail: sl(),
    );
  });

  sl.registerLazySingleton<EmailVerificationDuringEmailChangeController>(() {
    return EmailVerificationDuringEmailChangeControllerImpl(
      verifyEmailDuringEmailChange: sl(),
    );
  });

  sl.registerLazySingleton<PasswordChangeController>(() {
    return PasswordChangeControllerImpl(
      changePassword: sl(),
    );
  });

  sl.registerLazySingleton<PasswordResetRequestController>(() {
    return PasswordResetRequestControllerImpl(
      requestPasswordReset: sl(),
    );
  });

  sl.registerLazySingleton<PasswordResetController>(() {
    return PasswordResetControllerImpl(
      resetPassword: sl(),
    );
  });

  sl.registerLazySingleton<UserDeletionController>(() {
    return UserDeletionControllerImpl(
      deleteUser: sl(),
    );
  });

  sl.registerLazySingleton<UserGettingController>(() {
    return UserGettingControllerImpl(
      getUser: sl(),
    );
  });

  // use cases

  sl.registerLazySingleton<ChangeEmail>(() {
    return ChangeEmailImpl(
      userRepository: core_di.sl(),
      validateEmail: core_di.sl(),
      emailVerificationCodeRepository: core_di.sl(),
    );
  });

  sl.registerLazySingleton<ChangePassword>(() {
    return ChangePasswordImpl(
      validatePassword: core_di.sl(),
      userRepository: core_di.sl(),
      passwordService: core_di.sl(),
    );
  });

  sl.registerLazySingleton<DeleteUser>(() {
    return DeleteUserImpl(
      userRepository: core_di.sl(),
      appStoreUserToUserLinkRepository: core_di.sl(),
      googlePlayUserToUserLinkRepository: core_di.sl(),
    );
  });

  sl.registerLazySingleton<GetUser>(() {
    return GetUserImpl(
      userRepository: core_di.sl(),
    );
  });

  sl.registerLazySingleton<RequestPasswordReset>(() {
    return RequestPasswordResetImpl(
      userRepository: core_di.sl(),
      emailService: core_di.sl(),
      passwordResetTokenRepository: sl(),
    );
  });

  sl.registerLazySingleton<ResetPassword>(() {
    return ResetPasswordImpl(
      userRepository: core_di.sl(),
      passwordResetTokenRepository: sl(),
      passwordService: core_di.sl(),
      validatePassword: core_di.sl(),
    );
  });

  sl.registerLazySingleton<RunExpiredPasswordResetTokenDeletion>(() {
    return RunExpiredPasswordResetTokenDeletionImpl(
      passwordResetTokenRepository: sl(),
    );
  });

  sl.registerLazySingleton<VerifyEmailDuringEmailChange>(() {
    return VerifyEmailDuringEmailChangeImpl(
      userRepository: core_di.sl(),
      emailVerificationCodeRepository: core_di.sl(),
      validateEmail: core_di.sl(),
      emailService: core_di.sl(),
      issueEmailVerificationCode: core_di.sl(),
    );
  });

  // repositories

  sl.registerLazySingleton<PasswordResetTokenRepository>(() {
    return PasswordResetTokenRepositoryImpl(
      db: core_di.sl(),
    );
  });
}
